#include "tca9548a_i2c.h"
#include "../../Core/Inc/gpio.h"
#include "../../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h"
#include <stdint.h>

//=====================I2C_START======================//
void tca9548a_sda_pin_output_high(void);
void tca9548a_sda_pin_output_low(void);
void tca9548a_scl_pin_output_high();
void tca9548a_scl_pin_output_low();
void tca9548a_delay_us(int us);

#define tca9548a_DSA_PIN  GPIO_PIN_11
#define tca9548a_DSA_PORT GPIOB
#define tca9548a_SCL_PIN  GPIO_PIN_10
#define tca9548a_SCL_PORT GPIOB
void tca9548a_init_i2c_sensor_port(void)
{
    //
}
void tca9548a_i2c_test(void)
{
    tca9548a_sda_pin_output_high();
    tca9548a_scl_pin_output_high();
    tca9548a_delay_us(1);
    tca9548a_sda_pin_output_low();
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(1);
}

void tca9548a_delay_us(int us)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < us; i++)
    {
        for (j = 0; j < 16; j++)
        {
            __NOP();
        }
    }
}

void tca9548a_sda_pin_output_high(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
    GPIO_InitStruct.Pin              = tca9548a_DSA_PIN;
    GPIO_InitStruct.Mode             = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull             = GPIO_NOPULL;
    GPIO_InitStruct.Speed            = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(tca9548a_DSA_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(tca9548a_DSA_PORT, tca9548a_DSA_PIN, GPIO_PIN_SET);
}

void tca9548a_sda_pin_output_low(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
    GPIO_InitStruct.Pin              = tca9548a_DSA_PIN;
    GPIO_InitStruct.Mode             = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull             = GPIO_NOPULL;
    GPIO_InitStruct.Speed            = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(tca9548a_DSA_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(tca9548a_DSA_PORT, tca9548a_DSA_PIN, GPIO_PIN_RESET);
}
void tca9548a_sda_pin_input(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
    GPIO_InitStruct.Pin              = tca9548a_DSA_PIN;
    GPIO_InitStruct.Mode             = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull             = GPIO_NOPULL;
    HAL_GPIO_Init(tca9548a_DSA_PORT, &GPIO_InitStruct);
}
uint8_t tca9548a_sda_pin_read_level()
{
    uint8_t level = 0;
    level         = HAL_GPIO_ReadPin(tca9548a_DSA_PORT, tca9548a_DSA_PIN);
    return level;
}
void tca9548a_scl_pin_output_high(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
    GPIO_InitStruct.Pin              = tca9548a_SCL_PIN;
    GPIO_InitStruct.Mode             = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull             = GPIO_NOPULL;
    GPIO_InitStruct.Speed            = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(tca9548a_SCL_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(tca9548a_SCL_PORT, tca9548a_SCL_PIN, GPIO_PIN_SET);
}

void tca9548a_scl_pin_output_low(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
    GPIO_InitStruct.Pin              = tca9548a_SCL_PIN;
    GPIO_InitStruct.Mode             = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull             = GPIO_NOPULL;
    GPIO_InitStruct.Speed            = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(tca9548a_SCL_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(tca9548a_SCL_PORT, tca9548a_SCL_PIN, GPIO_PIN_RESET);
}

void tca9548a_i2c_start(void)
{
    tca9548a_sda_pin_output_high();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_high();
    tca9548a_delay_us(8);
    tca9548a_sda_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(8);
}

void tca9548a_i2c_write_byte(uint8_t Byte)
{
    uint8_t Data, N, i;
    Data = Byte;
    i    = 0x80;
    for (N = 0; N < 8; N++)
    {
        tca9548a_scl_pin_output_low();
        tca9548a_delay_us(4);
        if (i & Data)
        {
            tca9548a_sda_pin_output_high();
        }
        else
        {
            tca9548a_sda_pin_output_low();
        }

        tca9548a_scl_pin_output_high();
        tca9548a_delay_us(4);
        Data <<= 1;
    }
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_sda_pin_input();
    tca9548a_delay_us(8);
}

uint8_t tca9548a_i2c_read_byte(void)
{
    uint8_t Byte, i, a;
    Byte = 0;
    tca9548a_scl_pin_output_low();
    tca9548a_sda_pin_input();
    tca9548a_delay_us(8);
    for (i = 0; i < 8; i++)
    {
        tca9548a_scl_pin_output_high();
        tca9548a_delay_us(5);
        if (tca9548a_sda_pin_read_level() == 1)
        {
            a = 1;
        }
        else
        {
            a = 0;
        }
        Byte = (Byte << 1) | a;
        tca9548a_scl_pin_output_low();
        tca9548a_delay_us(5);
    }
    tca9548a_sda_pin_input();
    tca9548a_delay_us(8);
    return Byte;
}

uint8_t tca9548a_i2c_wait_ack(void)
{
    uint8_t read = 0;
    uint8_t ack;
    tca9548a_scl_pin_output_low();
    tca9548a_sda_pin_input();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_high();
    tca9548a_delay_us(8);
    read = tca9548a_sda_pin_read_level();
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(8);
    ack = !read;
    return ack;
}

void tca9548a_i2c_send_ack(void)
{
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_sda_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_high();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_sda_pin_input();
    tca9548a_delay_us(8);
}

void tca9548a_i2c_send_Nack(void)
{
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_sda_pin_output_high();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_high();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_sda_pin_output_low();
    tca9548a_delay_us(8);
}

void tca9548a_i2_stop(void)
{
    tca9548a_sda_pin_output_low();
    tca9548a_delay_us(8);
    tca9548a_scl_pin_output_high();
    tca9548a_delay_us(8);
    tca9548a_sda_pin_output_high();
    tca9548a_delay_us(8);
}

//=====================I2C_END======================//

/* 核心兼容函数实现 */
HAL_StatusTypeDef Software_I2C_IsDeviceReady(I2C_HandleTypeDef* hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
{
    HAL_StatusTypeDef status = HAL_ERROR;

    while (Trials-- > 0)
    {
        /* 发送START条件 */
        tca9548a_i2c_start();

        /* 发送设备地址（带写标志） */
        uint8_t addr_byte = (DevAddress << 1) | 0x00;
        tca9548a_i2c_write_byte(addr_byte);

        /* 检查ACK */
        if (tca9548a_i2c_wait_ack() == 0)
        {
            status = HAL_OK;
            break;
        }

        /* 发送STOP条件 */
        tca9548a_i2_stop();

        /* 超时处理 */
        if (HAL_GetTick() > Timeout)
        {
            break;
        }
        HAL_Delay(1);
    }

    tca9548a_i2_stop();
    return status;
}

/* 优化后的I2C写函数（带HAL兼容） */
HAL_StatusTypeDef Software_I2C_Master_Transmit(I2C_HandleTypeDef* hi2c, uint16_t DevAddress, uint8_t* pData, uint16_t Size, uint32_t Timeout)
{
    // tca9548a_i2c_start();

    // /* 发送设备地址 */
    // uint8_t addr_byte = (DevAddress << 1);
    // tca9548a_i2c_write_byte(addr_byte);
    // if (tca9548a_i2c_wait_ack())
    // {
    //     tca9548a_i2_stop();
    //     return HAL_ERROR;
    // }

    // /* 发送数据 */
    // // while (Size--)
    // // {
    //     // tca9548a_i2c_write_byte(*pData++);
    //     tca9548a_i2c_write_byte(*pData);
    //     if (tca9548a_i2c_wait_ack())
    //     {
    //         tca9548a_i2_stop();
    //         return HAL_ERROR;
    //     }
    // // }

    // tca9548a_i2_stop();
    tca9548a_i2c_start();
    tca9548a_i2c_write_byte(DevAddress << 1);
    tca9548a_i2c_wait_ack();
    while (Size--)
    {
        tca9548a_i2c_write_byte((uint8_t)*pData++);
        tca9548a_i2c_wait_ack();
    }
    tca9548a_i2_stop();
    return HAL_OK;
}

HAL_StatusTypeDef Software_I2C_Master_Receive(I2C_HandleTypeDef* hi2c, uint16_t DevAddress, uint8_t* pData, uint16_t Size, uint32_t Timeout)
{
    // 忽略hi2c和Timeout参数（或根据需求扩展超时处理）
    // 转换设备地址为读模式（7位地址左移1位 + 读位1）
    uint8_t readAddr = (DevAddress << 1) | 0x01;

    // 发送起始条件
    tca9548a_i2c_start();

    // 发送设备地址（读）
    tca9548a_i2c_write_byte(readAddr);

    // 检查从机ACK
    if (tca9548a_i2c_wait_ack() == 0)
    {
        tca9548a_i2_stop();
        return HAL_ERROR;  // 无ACK，返回错误
    }

    // 读取数据字节
    for (uint16_t i = 0; i < Size; i++)
    {
        if (i == Size - 1)
        {
            // 最后一个字节，发送NACK
            pData[i] = tca9548a_i2c_read_byte();
            tca9548a_i2c_send_Nack();
        }
        else
        {
            pData[i] = tca9548a_i2c_read_byte();
            tca9548a_i2c_send_ack();
        }
    }

    // 发送停止条件
    tca9548a_i2_stop();

    return HAL_OK;
}
//=====================I2C_END======================//